import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
/**
 * F21AS Assignment Stage 1
 * Collection of input files and output files
 * @author Freddy Wong
 */

public class Collection {
/**
 * intialialize private variables
 **/
 
	public final static String NL = System.lineSeparator();
	private HashSet<Car> allCars;
	private TreeSet <Destination> allDestination;
	private ArrayList<Journey> allJourney2015;
	private HashSet<Journey> allJourney2014;
	private TreeMap <String, TreeSet<String>> driverDestination;
	private StringBuilder report;
	private StringBuilder report1;
	private StringBuilder report2;
	//constructor
	
	public Collection() {
		driverDestination = new TreeMap <String, TreeSet<String>>();
		driverDestination = new TreeMap <String, TreeSet<String>>();
		allCars = new HashSet<Car>();
		allDestination = new TreeSet<Destination>();
		allJourney2015 = new ArrayList<Journey>();
		allJourney2014 = new HashSet<Journey>();
		report = new StringBuilder();
		report1 = new StringBuilder();
		report2 = new  StringBuilder();
	}
	
public void output() { }
/**
 * method to read files
 * @param file
 * @throws IOException
 */
   
	public void readFile(String file) throws IOException {
		
		String fileName;
		fileName = file;
		try {
			File inputFile = new File (fileName);
			Scanner line = new Scanner(inputFile);
			while(line.hasNextLine()) {
				String inputLine = line.nextLine();
				if(inputLine.length() !=0 && fileName == "taxi.txt") {
					processLineOfCar(inputLine);
				}
				else if(inputLine.length() !=0 && fileName == "destination.txt") {
					processLineOfDestination(inputLine);
				}
				else if(inputLine.length() !=0 && fileName == "journeys2015.txt") {
					processLineOfJourney(inputLine);
				}
				else if(inputLine.length() !=0 && fileName == "journeys2014.txt") {
					processLineOfJourney1(inputLine);
				}
			}
			line.close();
			}
		catch (FileNotFoundException fnf) {
			System.out.println("File not found ");
			System.exit(0);
		}
	} // end of READFILE OF CAR
	
	/**
	 * get records from text file and remove "," before loaded into array list for processing
	 * @param line
	 */
	private void processLineOfCar(String line) {
				
		try {
			String parts [] = line.split(",");
			String registrationNumber = parts[0];
			Name driverName = new Name (parts[1]);		
			
			Car newCar = new Car(registrationNumber, driverName);
			//this.addCars(newCar);
			allCars.add(newCar);
		}
		catch (NumberFormatException nfe) {
			String error = "Number conversion error in " +line+ " " + nfe.getMessage();
			System.out.println(error);
		}
		catch (ArrayIndexOutOfBoundsException air) {
			String error = "Not enought items in: " +line+ " index position: " + air.getMessage();
			System.out.println(error);
		} catch (Exception e) {
			e.printStackTrace();
		}
	} //end of PROCESSLINE OF CAR

	/**
	 * get records from text file and remove "," before loaded into array list for processing
	 * @param line
	 */
	private void processLineOfDestination(String line) {
				
		try {
			String parts [] = line.split(",");
			String destination = parts[0];
			double distance = Double.parseDouble(parts[1]);	
			
			Destination newDestination = new Destination(destination, distance);
			//this.addDestination(newDestination);
			allDestination.add(newDestination);
		}
		catch (NumberFormatException nfe) {
			String error = "Number conversion error in " +line+ " " + nfe.getMessage();
			System.out.println(error);
		}
		catch (ArrayIndexOutOfBoundsException air) {
			String error = "Not enought items in: " +line+ " index position: " + air.getMessage();
			System.out.println(error);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	} //end of PROCESSLINE OF Destination
	
	/**
	 * get records from text file and remove "," before loaded into array list for processing
	 * @param line
	 */
	private void processLineOfJourney(String line) {
				
		try {
		    Car taxi = null;
		    Destination destination = null;
			String parts [] = line.split(",");
		    String registrationNumber = parts[0];
		    String location = parts[1];
		    int seats = Integer.parseInt(parts[2]);
		    int year = Integer.parseInt(parts[3]);
            
		    for(Car car : allCars) {
		    	if(registrationNumber.equals(car.getRegistrationNumber())) {
		    			taxi = car;
		    	}
		    }
		    
		    for(Destination place : allDestination) {
		    	if(location.equals(place.getDestination())) {
		    		destination = place;
		    		
		    	}
		    }
			Journey newTrip = new Journey(taxi, destination, seats, year);
			allJourney2015.add(newTrip);
		
		}
		catch (NumberFormatException nfe) {
			String error = "Number conversion error in " +line+ " " + nfe.getMessage();
			System.out.println(error);
		}
		catch (ArrayIndexOutOfBoundsException air) {
			String error = "Not enought items in: " +line+ " index position: " + air.getMessage();
			System.out.println(error);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//for (Journey j : allJourney2015)
		//{System.out.println (j);}//end of PROCESSLINE OF JOURNEY 2014
	} //end of PROCESSLINE OF JOURNEY 2015
	
	/**
	 * get records from text file and remove "," before loaded into array list for processing
	 * @param line
	 */
	private void processLineOfJourney1(String line) {
				
		try {

		    Destination destination = null;
			String parts [] = line.split(",");
		    String location = parts[0];
		    int year = Integer.parseInt(parts[1]);
            
		    for(Destination place : allDestination) {
		    	if(location.equals(place.getDestination())) {
		    		destination = place;
		    	}
		    }
			Journey oldTrip = new Journey(destination, year);
			allJourney2014.add(oldTrip);

		}
		catch (NumberFormatException nfe) {
			String error = "Number conversion error in " +line+ " " + nfe.getMessage();
			System.out.println(error);
		}
		catch (ArrayIndexOutOfBoundsException air) {
			String error = "Not enought items in: " +line+ " index position: " + air.getMessage();
			System.out.println(error);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
/**
 * method to print 5 most expensive journey
 */
	public void top5ExpensiveTrip(){
	    	
		    Collections.sort(allJourney2015,new CompareJourneyCost());
			if (allJourney2015.size() > 4)
			{
				for(int i = 0; i < 5; i++){
					report.append(allJourney2015.get(i).getCar().getRegistrationNumber() + "  " + allJourney2015.get(i).getDestination()+ "  " + 
							+ allJourney2015.get(i).getDestination().getDistance() + allJourney2015.get(i).getPassenger()+
							" miles  cost " + allJourney2015.get(i).getBill()).append(NL);
				}
			}
			
			System.out.println(report);
			
			}	
/**
 * method to get 5 most expensive journey  
 */
		    public void top5CheapTrip(){
		    	 Collections.sort(allJourney2015, new CompareJourneyCost());
		    	 for(int i = allJourney2015.size()-1; i  > ((allJourney2015.size()-1)-5); i--){//loop through collection allJourney2015
		    				report1.append(allJourney2015.get(i).getCar().getRegistrationNumber() + "  " + allJourney2015.get(i).getDestination()+ "  " + 
		    						+ allJourney2015.get(i).getDestination().getDistance() + allJourney2015.get(i).getPassenger()+
		    						" miles cost " + allJourney2015.get(i).getBill()).append(NL);
		    			}	System.out.println(report1);
		    		
		    		}	
/**
 * method to get  driver and destination they have been to
 */
		    public void getDriverDestinations(){
		    	
		    	String name = "";
		    
		    	for (Car c : allCars)//loop through car collections
		    	{
		    		name = c.getDriverName().getFullName();//get the name of driver
		    		TreeSet <String>des = new TreeSet<String>();
		    	for (Journey j1: allJourney2015)
		    		{  
		    		
		    		 if (j1.getCar().getDriverName().getFullName().equals(name))
		    			 des.add(j1.getDestination().getDestination());//Unique destinations
		    		}
		    		driverDestination.put(name, des);//add to map with driver name as the key and destinations as values
		    	}
		    	for(Map.Entry<String, TreeSet<String>> entry : driverDestination.entrySet()){
		    		report2.append(entry.getKey() + "  had driven to  " + entry.getValue()).append(NL);//loop through to print out reports
		    	}
		    	System.out.println(report2);
		    }

	}


